# Transformation ohne Force — Entscheidungslogik

Die zentrale Methode ist `is_up_to_date()` in transform.py:155-180. Sie basiert auf Modifikationszeiten (mtime), nicht auf Hashes.

## Ablauf
Die Prüfung erfolgt an zwei Stellen in der Pipeline:
1. Vor Saxon-Transformation (`transform_saxon()`) — transform.py:192-194
2. Vor PDF-Build (`build_pdf()`) — transform.py:322-324

Beide rufen `is_up_to_date()` auf, die prüft:
- Existiert die New-PDF?
- Ist die XML-Datei neuer als die New-PDF?
- Ist die XSL-Datei neuer als die New-PDF?

Wenn die New-PDF existiert und älter als alle Inputs ist → Transformation wird übersprungen mit `(True, "Übersprungen (aktuell)")`.

## Mermaid-Diagramm
```mermaid
flowchart TD
    A["Transformation gestartet<br/>(force=False)"] --> B{"force == True?"}
    B -- Ja --> EXEC["Transformation ausführen"]
    B -- Nein --> C{"New-PDF existiert?"}
    C -- Nein --> EXEC
    C -- Ja --> D["mtime der New-PDF ermitteln"]
    D --> E{"XML-Datei neuer<br/>als New-PDF?"}
    E -- Ja --> EXEC
    E -- Nein --> F{"XSL-Datei neuer<br/>als New-PDF?"}
    F -- Ja --> EXEC
    F -- Nein --> SKIP["Übersprungen (aktuell)<br/>return (True, 'Übersprungen')"]

    EXEC --> S1["Schritt 1: Saxon<br/>XML → FO"]
    S1 --> S1OK{"Saxon erfolgreich?"}
    S1OK -- Nein --> FAIL["Pipeline abgebrochen"]
    S1OK -- Ja --> S2CHECK{"force == True?<br/>(erneute Prüfung<br/>für build_pdf)"}
    S2CHECK -- Ja --> S2["Schritt 2: FOP<br/>FO → PDF"]
    S2CHECK -- Nein --> S2UP{"is_up_to_date()?"}
    S2UP -- Ja --> S2SKIP["PDF-Build übersprungen"]
    S2UP -- Nein --> S2
    S2 --> S3["Schritt 3: diff-pdf<br/>PDF-Vergleich"]
    S3 --> DONE["Pipeline abgeschlossen"]

    style SKIP fill:#4CAF50,color:#fff
    style EXEC fill:#2196F3,color:#fff
    style FAIL fill:#f44336,color:#fff
    style DONE fill:#4CAF50,color:#fff
    style S2SKIP fill:#4CAF50,color:#fff
```
## Wichtige Details
- Keine Hash-basierte Prüfung: Die Skip-Logik nutzt ausschließlich `mtime`-Vergleiche, nicht die blake2b-Hashes (die werden nur für Änderungsverfolgung in der UI verwendet).
- Doppelte Prüfung: `is_up_to_date()` wird sowohl vor Saxon als auch vor FOP aufgerufen — theoretisch könnte Saxon ausgeführt, aber der PDF-Build übersprungen werden.
- Skip = Erfolg: Ein übersprungener Schritt gilt als erfolgreich `(True, ...)`, die Pipeline läuft weiter.
- Force-Aufruf: Über das Kontextmenü gibt es explizite Force-Methoden wie `_transform_all_xml_files_force()` in transformation.py.


## Erweiterung

```mermaid
flowchart TD
    LOAD["Projekt geladen"] --> BUILD["XSL-Abhängigkeitsgraph aufbauen<br/>dict[Path, set[Path]]"]
    BUILD --> CACHE["Im Speicher halten"]

    TRANSFORM["is_up_to_date() aufgerufen"] --> CHECK{"Graph-Eintrag<br/>vorhanden?"}
    CHECK -- Nein --> PARSE["XSL parsen, Imports auflösen,<br/>Eintrag erstellen"]
    PARSE --> MTIME
    CHECK -- Ja --> STALE{"mtime der XSL<br/>geändert seit letztem Parse?"}
    STALE -- Ja --> PARSE
    STALE -- Nein --> MTIME["mtime aller Abhängigkeiten<br/>gegen New-PDF prüfen"]
    MTIME --> RESULT["Ergebnis"]
```